-----------------------------------------------------------------------------------------------------------------------------------------
--commonTools
-----------------------------------------------------------------------------------------------------------------------------------------
local localStrLuaName="CommonUtilities.lua"
-----------------------------------------------------------------------------------------------------------------------------------------------
-- 	跳过字符串开头的空白
--	返回跳过后的字符串
-----------------------------------------------------------------------------------------------------------------------------------------------
function skipHeadSpace(skipString)
	local headp =1
	while 1 do
		local byte = string.byte(skipString,headp)
		if nil == byte then
			return nil
		end
--		print(skipString,byte)
		if 32 ~= byte and 9 ~= byte then 
			break
		end
		headp = headp +1
	end
	skipString = string.sub(skipString,headp)
	return skipString
end
-----------------------------------------------------------------------------------------------------------------------------------------
--分解Option
-----------------------------------------------------------------------------------------------------------------------------------------
function parseOption2Token(option)
	local tmpTokenTable = {}
	local tmpToken ={}
	local counter = 1
	while 1 do
		local ch = string.byte(option,counter)
		counter = counter + 1
		if nil == ch then
			break
		end
		local split = 0
-- 遇到空格
		if " " == string.char(ch) then
			split = 1
		end
--分割
		if 1 == split then
			local tmpcout = table.maxn(tmpToken)
			if 0 < tmpcout then
				local tokenstring = table.concat(tmpToken,"")
				table.insert(tmpTokenTable,tokenstring)
				tmpToken ={}
			end
--不用分割
		else
			table.insert(tmpToken,string.char(ch))
		end
	end
--最后的Token
	local tmpcout = table.maxn(tmpToken)
	if 0 < tmpcout then
		local tokenstring = table.concat(tmpToken,"")
		table.insert(tmpTokenTable,tokenstring)
		tmpToken ={}
	end	
	return tmpTokenTable
end
-----------------------------------------------------------------------------------------------------------------------------------------
--以"/" "\"分解路径
-----------------------------------------------------------------------------------------------------------------------------------------
function parsePathe2Token(path)
	local tmpTokenTable = {}
	local tmpToken ={}
	local counter = 1
	while 1 do
		local ch = string.byte(path,counter)
		counter = counter + 1
		if nil == ch then
			break
		end
		local split = 0
-- 遇到"/"
		if "/" == string.char(ch) then
			split = 1
		end
--分割
-- 遇到"\"
		if "\\" == string.char(ch) then
			split = 1
		end
--分割
		if 1 == split then
			local tmpcout = table.maxn(tmpToken)
			if 0 < tmpcout then
				local tokenstring = table.concat(tmpToken,"")
				table.insert(tmpTokenTable,tokenstring)
				tmpToken ={}
			end
--不用分割
		else
			table.insert(tmpToken,string.char(ch))
		end
	end
--最后的Token
	local tmpcout = table.maxn(tmpToken)
	if 0 < tmpcout then
		local tokenstring = table.concat(tmpToken,"")
		table.insert(tmpTokenTable,tokenstring)
		tmpToken ={}
	end	
	return tmpTokenTable
end
-----------------------------------------------------------------------------------------------------------------------------------------
--以"patern"分解字符串
-----------------------------------------------------------------------------------------------------------------------------------------
function parseString2Token(srcString,patern)
	local tmpTokenTable = {}
	local tmpToken ={}
	local counter = 1
	while 1 do
		local ch = string.byte(srcString,counter)
		counter = counter + 1
		if nil == ch then
			break
		end
		local split = 0
-- 遇到patern
		if patern == string.char(ch) then
			split = 1
		end
--分割
		if 1 == split then
			local tmpcout = table.maxn(tmpToken)
			if 0 < tmpcout then
				local tokenstring = table.concat(tmpToken,"")
				table.insert(tmpTokenTable,tokenstring)
				tmpToken ={}
			end
--不用分割
		else
			table.insert(tmpToken,string.char(ch))
		end
	end
--最后的Token
	local tmpcout = table.maxn(tmpToken)
	if 0 < tmpcout then
		local tokenstring = table.concat(tmpToken,"")
		table.insert(tmpTokenTable,tokenstring)
		tmpToken ={}
	end	
	return tmpTokenTable
end
-----------------------------------------------------------------------------------------------------------------------------------------
--dump  table 
-----------------------------------------------------------------------------------------------------------------------------------------
function debug_dump_Table_recall(t,dst,level)
	local lv = level
	local space=""
	while lv > 1 do
		lv = lv -1
		space = space.."\t"
	end
	table.insert(dst,space)
	table.insert(dst,"{")
	for i,v in pairs(t) do
		if "table" ~= type(v) then
			table.insert(dst,v)
			if i ~= table.maxn(t) then
				table.insert(dst,",")
			end
		end
	end
	for i,v in pairs(t) do
		if "table" == type(v) then
			table.insert(dst,i.."=".."\n")
			debug_dump_Table_recall(v,dst,level +0 )
		end
	end
--	table.insert(dst,space)
	table.insert(dst,"}\n")
end
-----------------------------------------------------------------------------------------------------------------------------------------
--dump  table 
-----------------------------------------------------------------------------------------------------------------------------------------
function debug_dump_Table(name,t)
	local tmpdumpInfo = {name,"=\n"}
	debug_dump_Table_recall(t,tmpdumpInfo,1)
	print(table.concat(tmpdumpInfo," "))
end

-----------------------------------------------------------------------------------------------------------------------------------------------
--cat Lua文件
-----------------------------------------------------------------------------------------------------------------------------------------------
function catLuaFile(src)
	for line in io.lines(src) do
		io.write(line,"\n")
	end
end
----------------------------------------------------------------------------------------------------------------------------------------
--分解Command字符串成Token
-----------------------------------------------------------------------------------------------------------------------------------------
function parseCommand2Token(command)
	local tmpTokenTable = {}
	local tmpToken ={}
	local counter = 1
	while 1 do
		local ch = string.byte(command,counter)
		counter = counter + 1
		if nil == ch then
			break
		end
		local split = 0
-- 遇到空格
		if " " == string.char(ch) then
			split = 1
		end
--分割
		if 1 == split then
			local tmpcout = table.maxn(tmpToken)
			if 0 < tmpcout then
				local tokenstring = table.concat(tmpToken,"")
				table.insert(tmpTokenTable,tokenstring)
				tmpToken ={}
			end
--不用分割
		else
			table.insert(tmpToken,string.char(ch))
		end
	end
--最后的Token
	local tmpcout = table.maxn(tmpToken)
	if 0 < tmpcout then
		local tokenstring = table.concat(tmpToken,"")
		table.insert(tmpTokenTable,tokenstring)
		tmpToken ={}
	end	
	return tmpTokenTable
end

-----------------------------------------------------------------------------------------------------------------------------------------
--Token合并
--现在只处理${变量} pattern->$,{,*,} 表
--将来处理更多种类合并
-----------------------------------------------------------------------------------------------------------------------------------------
function jointTokenByFormat(tokenTable,pattern)
	local tokenCounter = 1
	local ret ={}
	while 1 do
		local token = tokenTable[tokenCounter]
		if nil == token then
			break
		end
		if "$" == token then
			local varToken = table.concat(tokenTable,"",tokenCounter,tokenCounter+3)
			tokenCounter = tokenCounter + 4
			table.insert(ret,varToken)
		else
			tokenCounter = tokenCounter + 1
			table.insert(ret,token)
		end
--	print(token)
	end
	return ret
end
-----------------------------------------------------------------------------------------------------------------------------------------
--表里面查找数据
--找到的话返回index
--没有找到的话返回NIL
-----------------------------------------------------------------------------------------------------------------------------------------
function findTableMember(member,distTable)
	for i,v in pairs(distTable) do
		if v == member then
			return i
		end
	end
	return nil
end
-----------------------------------------------------------------------------------------------------------------------------------------
--Token表替换
-----------------------------------------------------------------------------------------------------------------------------------------
function commonTokenReplace(srcTable,parterTable)
	local ret = {}
	for i,v in pairs(srcTable) do
		local replace = parterTable[v]
		if nil == replace then
			table.insert(ret,v)
		elseif "table" == type(replace) then
			for k,z in pairs(replace) do
				table.insert(ret,z)
			end
		else
			table.insert(ret,replace)
		end
	end
	return ret
end
-----------------------------------------------------------------------------------------------------------------------------------------
--表整理函数群
-----------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------
--展开表中${变量}
-----------------------------------------------------------------------------------------------------------------------------------------
function extractVarTable(distTable,setDataTable)
	local ret ={}
	for i,token in pairs(distTable) do
		if "table" == type(token) then
			ret[i] = extractVarTable(token,setDataTable)
		elseif "$" ~= string.char(string.byte(token,1)) then
			ret[i] = token
		else
			local length = string.len(token)
			local var = string.sub(token,3,length - 1 )
			local data = setDataTable[var]
			if nil == data then
--				globalTableErrorHandlerInfo["luaFile"] = localStrLuaName
--				globalTableErrorHandlerInfo["Resean"] = " can not fond set data"
--				globalTableErrorHandlerInfo["Token"] = var
--				dofile(globalStrLLMakeErrorHandler)
				print("Warning "..token.." not defined ")
				ret[i] = " "
			else
				ret[i] = data
			end
		end
	end
	return ret
end
-----------------------------------------------------------------------------------------------------------------------------------------
--降低Table的深度
-----------------------------------------------------------------------------------------------------------------------------------------
function reduceTableDepth(distTable)
	local ret ={}
	for i,v in pairs(distTable) do
		if "table" == type(v) then
			if "number" == type(i) then
				for j,z in pairs (v) do
					table.insert(ret,z)
				end
			else
				ret[i] = reduceTableDepth(v)
			end
		else
			ret[i] = v
		end
	end
	return ret
end
-----------------------------------------------------------------------------------------------------------------------------------------
--包涵"./" "../"路径整理成绝对路径
-----------------------------------------------------------------------------------------------------------------------------------------
function checkAndSimplePath(path)
	local pathToken = {}
	local firstCh = string.byte(path,1)
	pathToken = parsePathe2Token(path)
-- 不是path 
	if 2 > table.maxn(pathToken) then
		return path
	end
--整理Path
	local retTable = {}
	for i,v in pairs(pathToken) do
		if ".." == v then
			table.remove(retTable)
		elseif "." ~= v then
			table.insert(retTable,v)
		end
	end
	local ret = table.concat(retTable,"/")
	if "/" == string.char(firstCh) then
		ret = "/"..ret
	end
	return ret
end
-----------------------------------------------------------------------------------------------------------------------------------------
--baseName取得
-----------------------------------------------------------------------------------------------------------------------------------------
function luaGetBaseName(path)
	local pathToken = {}
--	print(path)
	pathToken = parsePathe2Token(path)
--	for i,v in pairs (pathToken) do
--		print(i,v)
--	end
	local leng = table.maxn(pathToken)
	local ret = pathToken[leng]
--	print(ret,leng)
	return ret
end
-----------------------------------------------------------------------------------------------------------------------------------------
--pathName取得
-----------------------------------------------------------------------------------------------------------------------------------------
function luaGetPathName(path)
	local pathToken = {}
	pathToken = parsePathe2Token(path)
	local tail = table.maxn(pathToken) - 1
	return table.concat(pathToken,"/",1,tail)
end

-----------------------------------------------------------------------------------------------------------------------------------------
--合并表
-----------------------------------------------------------------------------------------------------------------------------------------
function jointTable(table1,table2)
	local t = table1
	for i,v in pairs(table2) do
		if nil == table1[i] then
			t[i] = v
		elseif "table" ~= type(v) and "table" ~= type(table1[i]) then
			local newTable ={table1[i],v}
			t[i] = newTable
		elseif "table" ~= type(v) and "table" == type(table1[i]) then
			table.insert(table1[i],v)
			t[i] = table1[i]
		elseif "table" == type(v) and "table" ~= type(table1[i]) then
			table.insert(v,table1[i])
			t[i] = v
		elseif "table" == type(v) and "table" == type(table1[i]) then
			t[i] = jointTable(table1[i],v)
		end
	end
	return t
end

-----------------------------------------------------------------------------------------------------------------------------------------
--无冲突表差入
-----------------------------------------------------------------------------------------------------------------------------------------
function noneConflictInsert(tbl,var)
	for i,v in pairs(tbl) do
		if var == v then
			return nil
		end
	end
	table.insert(tbl,var)
	return nil
end
-----------------------------------------------------------------------------------------------------------------------------------------
--展开表中${变量} 返回字符串
-----------------------------------------------------------------------------------------------------------------------------------------
function extractVariableValue(distTable,setDataTable)
	local retTable ={}
	for i,token in pairs(distTable) do
		if "table" == type(token) then
			local subString = extractVariableValue(token)
			table.insert(retTable,subString)
		elseif "string" == type(token) or "number" == type(token) then
			local TokenTable = {}
			TokenTable = nativeToolString2Token(token,"","${}")
			if nil == TokenTable then
				os.exit(-1)
			end
			if "$" == TokenTable[1] and nil ~= setDataTable then
				table.remove(TokenTable,1)
				table.remove(TokenTable,1)
				table.remove(TokenTable)
				local key = table.concat(TokenTable,"")
				local var = setDataTable[key]
				if nil ~= var then
					table.insert(retTable,var)
				else
					print("Warning: ${"..key.."} use no defined variable")
				end
			else
				table.insert(retTable,token)
			end
		else
			print("Warning:LLMake team program miss,we will find it")
		end
	end
	return retTable
end

-----------------------------------------------------------------------------------------------------------------------------------------
--展开中${变量} 返回字符串
-----------------------------------------------------------------------------------------------------------------------------------------
function checkAndRepleaceVariableValue(var,setDataTable)
	local retString = ""
	local replaceTokenTable = nativeToolString2Token(var,"","${}")
	if nil == replaceTokenTable then
		os.exit(-1)
	end
	if "$" == replaceTokenTable[1] then
		table.remove(replaceTokenTable,1)
		table.remove(replaceTokenTable,1)
		table.remove(replaceTokenTable)
		local key = table.concat(replaceTokenTable,"")
		local replace = setDataTable[key]
		if nil ~= replace then
			retString =  replace
		else
			print("Warning:use no defined variable")
		end
	else
		retString =  var
	end
	return retString
end

-----------------------------------------------------------------------------------------------------------------------------------------
--Lex的Token替换
-----------------------------------------------------------------------------------------------------------------------------------------
function lexTokenReplace(lexTable,parterToken)
	local retTable={}
	for i,v in pairs(lexTable) do
		local TokenTable = {}
		TokenTable = nativeToolString2Token(v," ","()")
		if nil == TokenTable then
			os.exit(-1)
		end
		for k,z in pairs(TokenTable) do
			local replace = parterToken[z]
			if replace then
				TokenTable[k] = replace
			end
		end
		local lex= table.concat(TokenTable," ")
		table.insert(retTable,lex)
	end
	return retTable
end

function createParseTargetDataTable()
	local t ={}
	t[gTableJointTokenTable] ={}
	t[gTableVariableName] ={}
	t[gTableVariableValue] ={}
	t[gTableVariableProperty] ={}
	t[gTableMacroName] ={}
	t[gTableMacroARGV] ={}
	t[gTableMacroLex] ={}
	t[gTableSubDirectory] ={}
	t[gTableTargetName] ={}
	t[gTableTargetSrc] ={}
	t[gTableTargetType] ={}
	t[gTableTargetPath] ={}
	t[gTableCFLAGS] ={}
	t[gTableCXXFLAGS] ={}
	t[gTableLDFLAGS] ={}
	t[gTableIncludeDirectories] ={}
	t[gTableLinkDirectories] ={}
	t[gTableDefinitions] ={}
	t[gTableRequiredPackage] ={}
	t[gTableTargetLink] ={}
	return t
end
function createDirectoryTreeTable()
	local t ={}
	t[gStringDirectoryTreeLuaFile] =""
	t[gTableDirectoryTreeRoot]=""
	t[gTableDirectoryTreeSub] ={}
	return t
end

function extractVariableOfParseTargetDataTable(t)
	for i,v in pairs(t) do
		if gTableSubDirectory == i then
			for k,z in pairs(v) do
				extractVariableOfParseTargetDataTable(z)
			end
		elseif  gTableVariableName ~= i and gTableVariableValue ~= i and gTableVariableProperty ~= i 
			and gTableMacroName ~= i and gTableMacroARGV ~= i and gTableMacroLex ~= i 		then
			t[i] = extractVarTable(v,t[gTableVariableValue])
		end
	end
	return nil
end
-----------------------------------------------------------------------------------------------------------------------------------------
--checkFileExistance函数开始
-----------------------------------------------------------------------------------------------------------------------------------------
function checkFileExistance(path)
	local file = io.open(path,"r")
	if file then
		io.close(file)
		return true
	else
		return false
	end
end

-----------------------------------------------------------------------------------------------------------------------------------------
--getJointVariableNumber函数开始
-----------------------------------------------------------------------------------------------------------------------------------------
function getJointVariableNumber(varTable,JointTokenTable)
	local ret = {}
	local jointVar =""
	local jointStart = 1
	local jointEnd = 1
	local dstString=table.concat(JointTokenTable," ")
	for i,v in pairs(varTable) do
		jointVar = jointVar..v
		local p,q = string.find(dstString,jointVar)
--		print(i,v,p,q)
		if nil ==p and nil ==q then
			if jointEnd > jointStart then
				table.insert(ret,{jointStart,jointEnd})
			end
			jointVar =""
			jointStart = i
			jointEnd = i
		else
			jointEnd = i
		end
	end
--	print(jointStart,jointEnd)
	if jointEnd > jointStart then
		table.insert(ret,{jointStart,jointEnd})
	end
	return ret
end
-----------------------------------------------------------------------------------------------------------------------------------------
--合并简单不包含表，并且不用下表的表
-----------------------------------------------------------------------------------------------------------------------------------------
function jointSimpleTable(table1,table2)
	local t ={}
	if table1 then
		t = table1
	end
	if nil == table2 then
		return t
	end
	for i,v in ipairs(table2) do
		table.insert(t,v)
	end
	return t
end

-----------------------------------------------------------------------------------------------------------------------------------------
--Token""合并
-----------------------------------------------------------------------------------------------------------------------------------------
function jointTokenYinHao(tokenTable)
	local ret ={}
	local yinHao=false
	local joint=""
	for i,v in pairs(tokenTable) do
		if "\"" == v then
			joint = joint..v
			if yinHao then
				yinHao = false
--				print(joint)
				table.insert(ret,joint)
				joint = ""
			else
				yinHao = true
			end
		elseif yinHao then
			joint = joint..v
		else
--			print(joint)
			table.insert(ret,v)
		end
	end
	return ret
end
